package com.example.financecollegeorderdish.ui

import android.graphics.Typeface
import android.view.View
import android.widget.CheckBox
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import com.blankj.utilcode.util.FileIOUtils
import com.blankj.utilcode.util.PathUtils
import com.blankj.utilcode.util.TimeUtils
import com.bumptech.glide.Glide
import com.drake.brv.utils.divider
import com.drake.brv.utils.grid
import com.drake.brv.utils.linear
import com.drake.brv.utils.models
import com.drake.brv.utils.setup
import com.example.financecollegeorderdish.R
import com.example.financecollegeorderdish.bean.HealthRvBean
import com.example.financecollegeorderdish.bean.TasteRvBean
import com.example.financecollegeorderdish.databinding.ActivityMainBinding
import com.example.financecollegeorderdish.db.AppDatabase
import com.example.financecollegeorderdish.db.bean.DishBean
import com.example.financecollegeorderdish.ui.dialog.AboutDialog
import com.example.financecollegeorderdish.ui.dialog.DetailDialog
import com.example.financecollegeorderdish.ui.dialog.LoadingDialog
import com.example.financecollegeorderdish.ui.dialog.RatingDialog
import com.example.financecollegeorderdish.ui.poup.HealthTagPoup
import com.example.financecollegeorderdish.ui.poup.TasteTagPoup
import com.example.financecollegeorderdish.vm.MainViewModel
import com.google.gson.Gson
import com.lxj.xpopup.XPopup
import com.lxj.xpopup.core.BasePopupView
import com.lxj.xpopup.enums.PopupPosition
import com.lxj.xpopup.interfaces.SimpleCallback
import com.skydoves.powerspinner.DefaultSpinnerAdapter
import com.wuhao.lib_base.BaseApplication.context
import com.wuhao.lib_base.mvvm.v.BaseActivity
import com.wuhao.lib_common.utils.LoggerHelper
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.functions.Consumer
import io.reactivex.rxjava3.schedulers.Schedulers
import java.io.File


open class MainActivity : BaseActivity<ActivityMainBinding, MainViewModel>() {

    override val mViewModel: MainViewModel
        get() = MainViewModel()

    /**
     * 创建 [ViewBinding] 实例
     */
    override fun createVB(): ActivityMainBinding = ActivityMainBinding.inflate(layoutInflater)
    var tasteList: MutableList<TasteRvBean> = mutableListOf()
    var healthTagList: MutableList<HealthRvBean> = mutableListOf()

    /**
     * 2-订阅 [LiveData]
     */
    override fun initObserve() {
        mViewModel.tasteList.observe(this@MainActivity) {
            if (it.isNotEmpty()) {
                tasteList.clear()
                tasteList.addAll(it.filter { it.isNotEmpty() }.map { TasteRvBean(it, false) })
                mBinding.rvTaste.models = tasteList
            }
        }
        mViewModel.healthList.observe(this@MainActivity) {
            if (it.isNotEmpty()) {
                healthTagList.clear()
                var healthSet: MutableSet<String> = mutableSetOf()
                for (dishBean in it) {
                    healthSet.addAll(
                        Gson().fromJson(
                            dishBean.healthTag,
                            Array<String>::class.java
                        ).toSet()
                    )
                }
                healthTagList.addAll(healthSet.filter { it.isNotEmpty() }
                    .map { HealthRvBean(it, false) }.toList())
                mBinding.rvHealth.models = healthTagList
            }
        }
        mViewModel.mainRvList.observe(this@MainActivity) {
            var healthConditionList =
                (mBinding.rvHealth.models as List<HealthRvBean>).filter { it.isChecked }
                    .map { it.health }
            if (it.isNotEmpty()) {
                if (healthConditionList.isNotEmpty()) {
                    mBinding.rvDish.models = it.filter {
                        checkListContainment(
                            healthConditionList,
                            Gson().fromJson(it.healthTag, Array<String>::class.java).toList()
                        )
                    }
                } else {
                    mBinding.rvDish.models = it
                }
            }
        }
    }

    /**
     * 3-用于在页面创建时进行请求接口
     */
    override fun initRequestData() {
    }

    /**
     * 1-初始化 View
     */
    override fun ActivityMainBinding.initView() {
        mBinding.appName.typeface = pmzdbt
        mBinding.setting.typeface = pmzdbt
        mBinding.export.typeface = pmzdbt
        mBinding.about.typeface = pmzdbt
        mBinding.serviceEvaluate.typeface = pmzdbt
        mBinding.callService.typeface = pmzdbt

        mBinding.tvEatPersonNum.typeface = syht
        mBinding.tvTaste.typeface = syht
        mBinding.tvHealthTag.typeface = syht

        mBinding.setting.setOnClickListener {
            startActivity(ManageDishActivity::class.java)
            /*XPopup.Builder(this@MainActivity).asInputConfirm(
                "提醒", "请输入管理员密码以验证身份。"
            ) { text ->
                if (text=="888888") {
                    startActivity(ManageDishActivity::class.java)
                }else{
                    showWarning("对不起，您没有权限进行该操作")
                }
            }
                .show()*/
        }
        mBinding.export.setOnClickListener {
            exportAll()
        }

        initSpinner()
        initRv()

        mBinding.tvCancel.setOnClickListener {
            clearCondition()
        }
        mBinding.tvSure.setOnClickListener {
            XPopup.Builder(this@MainActivity)
                .dismissOnTouchOutside(false)
                .setPopupCallback(object : SimpleCallback() {
                    override fun onDismiss(popupView: BasePopupView?) {
                        super.onDismiss(popupView)
                        showSuccess("已根据您的需求为您推荐了以下菜品")
                    }
                })
                .asCustom(LoadingDialog(this@MainActivity, 1))
                .show()


            val map: List<String> = (mBinding.rvTaste.models as List<TasteRvBean>).filter {
                it.isChecked
            }.map { it.taste }
//            mViewModel.changeMainRvData(map)
            changeRvData(map)
        }
        mBinding.checkOk.setOnClickListener {
            val items = mBinding.rvDish.models as List<DishBean>
            val selectedList = mutableListOf<DishBean>()
            for (item in items) {
                if (item.isSelected) {
                    selectedList.add(item)
                }
            }
            SelectedActivity().start(this@MainActivity, Gson().toJson(selectedList))

        }
        mBinding.poupHealthGroup.setOnClickListener {
            XPopup.Builder(this@MainActivity)
                .dismissOnTouchOutside(true)
                .hasShadowBg(false)
                .setPopupCallback(object : SimpleCallback() {
                    override fun onDismiss(popupView: BasePopupView?) {
                        super.onDismiss(popupView)
                        var changedStr = ""
                        for (healthRvBean in healthTagList) {
                            if (healthRvBean.isChecked) {
                                changedStr += "${healthRvBean.health}、"
                            }
                        }
                        if (changedStr.isNotEmpty()) {
                            mBinding.tvHealthPoup.text = changedStr
                        } else {
                            mBinding.tvHealthPoup.text = "点击选择健康指症"
                        }
                    }
                })
                .popupPosition(PopupPosition.Bottom)
                .popupWidth(mBinding.poupHealthGroup.width)
                .atView(mBinding.tvHealthPoup)
                .asCustom(HealthTagPoup(this@MainActivity, healthTagList))
                .show()
        }
        mBinding.poupTasteGroup.setOnClickListener {
            XPopup.Builder(this@MainActivity)
                .dismissOnTouchOutside(true)
                .hasShadowBg(false)
                .popupPosition(PopupPosition.Bottom)
                .popupWidth(mBinding.poupHealthGroup.width)
                .setPopupCallback(object : SimpleCallback() {
                    override fun onDismiss(popupView: BasePopupView?) {
                        super.onDismiss(popupView)
                        var changedStr = ""
                        for (tasteRvBean in tasteList) {
                            if (tasteRvBean.isChecked) {
                                changedStr += "${tasteRvBean.taste}、"
                            }
                        }
                        if (changedStr.isNotEmpty()) {
                            mBinding.tvTastePoup.text = changedStr
                        } else {
                            mBinding.tvTastePoup.text = "点击选择口味"
                        }
                    }
                })
                .atView(mBinding.tvTastePoup)
                .asCustom(TasteTagPoup(this@MainActivity, tasteList))
                .show()
        }
        mBinding.callService.setOnClickListener {
            XPopup.Builder(this@MainActivity)
                .dismissOnTouchOutside(false)
                .setPopupCallback(object : SimpleCallback() {
                    override fun onDismiss(popupView: BasePopupView?) {
                        super.onDismiss(popupView)
                        showSuccess("已为您呼叫了服务员，请稍等...")
                    }
                })
                .asCustom(LoadingDialog(this@MainActivity, 2))
                .show()
        }
        mBinding.serviceEvaluate.setOnClickListener {
            XPopup.Builder(this@MainActivity)
                .dismissOnTouchOutside(true)
                .setPopupCallback(object : SimpleCallback() {
                    override fun onDismiss(popupView: BasePopupView?) {
                        super.onDismiss(popupView)
                    }
                })
                .asCustom(RatingDialog(this@MainActivity, this@MainActivity))
                .show()
        }
        mBinding.about.setOnClickListener {
            XPopup.Builder(this@MainActivity)
                .dismissOnTouchOutside(true)
                .setPopupCallback(object : SimpleCallback() {
                    override fun onDismiss(popupView: BasePopupView?) {
                        super.onDismiss(popupView)
                    }
                })
                .asCustom(AboutDialog(this@MainActivity))
                .show()
        }
        clearCondition()
    }

    val pmzdbt: Typeface by lazy {
        Typeface.createFromAsset(
            assets,
            "fonts/庞门正道标题体免费版.ttf"
        )
    }//旁门正道标题
    val syht: Typeface by lazy {
        Typeface.createFromAsset(
            assets,
            "fonts/庞门正道细线体.ttf"
        )
    }//思源黑体
    var checkedDishSet = mutableSetOf<Long>()

    // 初始化字体
    fun initRv() {
        mBinding.rvTaste.apply {
            linear()
            animation = null
            divider(R.drawable.shape_detail_rv_divider)
            setup {
                addType<TasteRvBean>(R.layout.item_rv_main)
                onBind {
                    val model = getModel<TasteRvBean>()
                    val cb = findView<CheckBox>(R.id.cb)
                    val title = findView<TextView>(R.id.title)
                    cb.isChecked = model.isChecked
                    title.text = model.taste
                }
                onClick(R.id.item) {
                    when (it) {
                        R.id.item -> {
                            val model = getModel<TasteRvBean>()
                            getModel<TasteRvBean>().isChecked =
                                !getModel<TasteRvBean>().isChecked
                            notifyItemChanged(modelPosition)
                        }

                        else -> {

                        }
                    }
                }
            }.models = arrayListOf()
        }
        mBinding.rvHealth.apply {
            linear()
            animation = null
            divider(R.drawable.shape_detail_rv_divider)
            setup {
                addType<HealthRvBean>(R.layout.item_rv_main)
                onBind {
                    val model = getModel<HealthRvBean>()
                    val cb = findView<CheckBox>(R.id.cb)
                    val title = findView<TextView>(R.id.title)
                    cb.isChecked = model.isChecked
                    title.text = model.health
                }
                onClick(R.id.item) {
                    when (it) {
                        R.id.item -> {
                            val model = getModel<HealthRvBean>()
                            getModel<HealthRvBean>().isChecked =
                                !getModel<HealthRvBean>().isChecked
                            notifyItemChanged(modelPosition)
                        }

                        else -> {

                        }
                    }
                }
            }.models = mutableListOf()
        }
        mBinding.rvDish.apply {
            grid(4)
            setup {
                addType<DishBean>(R.layout.rv_item_dish)
                animation = null
                onBind {
                    val model = getModel<DishBean>()
                    findView<TextView>(R.id.name).setText(model.name)
                    findView<TextView>(R.id.price).setText("RMB:${model.price}${getString(R.string.price)}")
                    val dishNum = findView<TextView>(R.id.dish_num)
                    val minus = findView<ImageView>(R.id.iv_minus)
                    val ivAdd = findView<ImageView>(R.id.iv_add)
                    dishNum.setText("${model.selectedNum}")
                    if (model.isSelected) {
                        minus.visibility = View.VISIBLE
                        dishNum.visibility = View.VISIBLE
                    } else {
                        minus.visibility = View.GONE
                        dishNum.visibility = View.GONE
                    }
                    val dishImg = findView<ImageView>(R.id.dish_img)
                    loadImage(model.imagePath, dishImg)
                }
                onClick(R.id.iv_add, R.id.iv_minus, R.id.item) {
                    val itemBean = getModel<DishBean>()
                    when (it) {
                        R.id.iv_add -> {
                            itemBean.selectedNum += 1
                            itemBean.isSelected = true
                            checkedDishSet.add(itemBean.primaryKey!!)
                            updateCheckedNum()
                            notifyDataSetChanged()
                        }

                        R.id.iv_minus -> {
                            if (itemBean.selectedNum > 1) {
                                itemBean.selectedNum -= 1
                            } else if (itemBean.selectedNum == 1) {
                                itemBean.selectedNum = 0
                                itemBean.isSelected = false
                                checkedDishSet.remove(itemBean.primaryKey!!)
                            }
                            updateCheckedNum()
                            notifyDataSetChanged()
                        }

                        R.id.item -> {
                            XPopup.Builder(this@MainActivity)
                                .autoOpenSoftInput(false)
                                .autoFocusEditText(false)
                                .dismissOnTouchOutside(true)
                                .asCustom(DetailDialog(context, itemBean))
                                .show()
                        }

                        else -> {}
                    }
                }
            }.models = mutableListOf()
        }
    }

    fun initSpinner() {
        mBinding.spinnerPersonNum.apply {
            setSpinnerAdapter(DefaultSpinnerAdapter(this))
            setItems(
                arrayListOf("不限", "1人", "2人", "3人", "4人")
            )
            getSpinnerRecyclerView().layoutManager = LinearLayoutManager(context)
            selectItemByIndex(0) // select a default item.
            lifecycleOwner = this@MainActivity
            setOnSpinnerItemSelectedListener<String> { oldIndex, oldItem, newIndex, newText ->
                when (newIndex) {
                    0 -> {
                        limitNum = 100
                    }

                    1 -> {
                        limitNum = 6
                    }

                    2 -> {
                        limitNum = 8
                    }

                    3 -> {
                        limitNum = 10
                    }

                    4 -> {
                        limitNum = 12
                    }

                    else -> {
                        limitNum = 100
                    }
                }
            }
        }

    }

    fun updateCheckedNum() {
        mBinding.checkOk.visibility = if (checkedDishSet.size > 0) {
            View.VISIBLE
        } else {
            View.GONE
        }
    }

    /**
     * 清除查询条件
     */
    fun clearCondition() {
        mBinding.spinnerPersonNum.selectItemByIndex(0)
        for (healthRvBean in healthTagList) {
            healthRvBean.isChecked = false
        }
        mBinding.tvHealthPoup.text = "点击选择健康指症"
        for (tasteRvBean in tasteList) {
            tasteRvBean.isChecked = false
        }
        mBinding.tvTastePoup.text = "点击选择口味"

        if (mBinding.rvTaste.models!!.isNotEmpty()) {
            val tasteModels = mBinding.rvTaste.models as MutableList<TasteRvBean>
            for (tasteM in tasteModels) {
                tasteM.isChecked = false
            }
            mBinding.rvTaste.models = tasteModels
        }
        mBinding.checkOk.visibility = View.GONE
        if (mBinding.rvHealth.models!!.isNotEmpty()) {
            val healthModels = mBinding.rvHealth.models as MutableList<HealthRvBean>
            for (healthM in healthModels!!) {
                healthM!!.isChecked = false
            }
            mBinding.rvHealth.models = healthModels
        }
//        mViewModel.changeMainRvData(listOf())
        changeRvData(listOf())
    }

    /**
     * 判断第一个List中的数据是否在第二个List中存在
     */
    fun checkListContainment(list1: List<String>, list2: List<String>): Boolean {
        for (item in list1) {
            if (list2.contains(item)) {
                return true
            }
        }
        return false
    }

    /**
     * 加载网络图片
     *
     * @param context   上下文
     * @param url       图片 URL
     * @param imageView 目标 ImageView
     */
    fun loadImage(url: String, imageView: ImageView) {
        //.error(R.mipmap.img_default_xh_target); // 错误图片
        Glide.with(this@MainActivity)
            .load(url)
            .into(imageView)
    }

    var limitNum: Int = 0
    fun changeRvData(tasteList: List<String>) {
        val dao = AppDatabase.getInstance(context).dishBeanDao()
        newRx.add(
            Observable.create<List<DishBean>> {
                if (tasteList.isEmpty()) {
                    val queryAllNoLive = dao.queryAllNoLive()
                    it.onNext(queryAllNoLive)
                } else {
                    val queryByCondition = dao.queryByCondition(tasteList, limitNum)
                    it.onNext(queryByCondition)
                }
            }.observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(
                    (Consumer<List<DishBean>> { data: List<DishBean> ->
//                    mViewModel.changeMainRvData(data)
                        showInRv(data)
                    }),
                    (Consumer<Throwable> { throwable: Throwable? ->
                        LoggerHelper.i(throwable!!.message)
                    })
                )
        )
    }

    fun showInRv(newData: List<DishBean>) {
        var healthConditionList =
            (mBinding.rvHealth.models as List<HealthRvBean>).filter { it.isChecked }
                .map { it.health }
        if (newData.isNotEmpty()) {
            if (healthConditionList.isNotEmpty()) {
                mBinding.rvDish.models = newData.filter {
                    val checkListContainment = checkListContainment(
                        healthConditionList,
                        Gson().fromJson(it.healthTag, Array<String>::class.java).toList()
                    )
                    if (checkListContainment
                    ) {
                        true
                    } else {
                        false
                    }
                }
            } else {
                mBinding.rvDish.models = newData
            }
        }
    }

    fun exportAll() {
        val dao = AppDatabase.getInstance(context).dishBeanDao()
        newRx.add(
            Observable.create<Boolean> {
                val allDish = dao.queryAllNoLive()
                if (allDish.isNotEmpty()) {
                    val writeFile = File(
                        "${PathUtils.getExternalStoragePath()}${File.separator}1菜悦云端${File.separator}${
                            TimeUtils.getNowString().replace(":", "-")
                        }.json"
                    )
                    FileIOUtils.writeFileFromString(writeFile, Gson().toJson(allDish))
                    it.onNext(true)
                } else {
                    it.onNext(false)
                }
            }.observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(
                    (Consumer<Boolean> { data: Boolean ->
                        if (data) {
                            showSuccess("导出成功")
                        } else {
                            showError("导出失败")
                        }
                    }),
                    (Consumer<Throwable> { throwable: Throwable? ->
                        LoggerHelper.i(throwable!!.message)
                    })
                )
        )
    }
}